-------------working and simulated---final-----------------------------------------------------------------
-- Company: 
-- Engineer:       Sneha Nidhi
-- 
-- Create Date:    00:33:02 12/07/2010 
-- Design Name: 
-- Module Name:    RS232_RX - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
--frequency of 20MHz and a transmission rate of 115200 bps
entity RS232_RX is
    Port ( 
			  Clk : in  STD_LOGIC;
           Reset : in  STD_LOGIC;--active high
           LineRD_in : in  std_logic;--rx rs232-activ low
			  Valid_out : out std_logic;--Indicates data is valid and should be stored in the shift register, active high.
			  Code_out  : out std_logic;--data output
           Store_out : out std_logic--Indicates that the byte rx is valid & should be shifted from shift register memory,active high.
			  );
  
  end RS232_RX;

architecture Behav of RS232_RX is

type state is (Idle,StartBit,RcvData,StopBit);
signal next_state,current_state : state;
signal Fifo_write :std_logic;--store out
--rst the counter at 1------------------
signal rst_datacounter :std_logic;--rst the data counter
signal rst_BitCounter :std_logic;--reset the 
signal en_counter:std_logic;--enable the count
---------------------------------------------------------------------------------------
signal DataCount : std_logic_vector(3 downto 0);---track of the bits rcvd
signal BitCounter : std_logic_vector(7 downto 0);--sampling in centre of the rx data

constant PulseEndOfCount:std_logic_vector(7 downto 0)  := "10101101"; -- 173
constant HalfPulseEndOfCount:std_logic_vector(7 downto 0)  := "01010111"; -- 88

begin
rst:process(Reset,current_state,LineRD_in,BitCounter,DataCount)
	 begin
		Code_out <= '0';    
		Valid_out <= '0';---indicates to store the valid incoming data in the shift register --Enable 
		Fifo_write <= '0';--write the data from the shift register to fifo if all the bits are rx 
	--default assignments---------------------------------------
		rst_datacounter<='0';--no rst
		rst_BitCounter<='0';--strt counting
		en_counter<='0';
	-------------------------------------------------------------------------	
		next_state <= current_state;
		if (Reset = '0') Then  
			next_state<= Idle;
		else 
		
		case current_state is
----------------------------------------------------------------------------						
		when Idle =>
			rst_BitCounter<='1';--rst
			rst_datacounter<='1';--rst
			if (LineRD_in='0')then --active low
				next_state <= StartBit; 
			end if;
----------------------------------------------------------------------------							 
		when StartBit=>
			rst_datacounter<='1';--rst
			if(BitCounter = HalfPulseEndOfCount) then
				next_state<=RcvData;
				rst_BitCounter<='1';
			end if;
---------------------------------------------------------------------------								
		when RcvData=>
			if (BitCounter = PulseEndOfCount) then--173
				en_counter<='1';
				Valid_out<='1';--indicates valid data
				Code_out <=LineRD_in;--value rx,is loaded in code_out->D in shift reg
				rst_BitCounter<='1';--rst
			end if;	
			if (DataCount = "1000") then
				next_state<= StopBit;
			end if;
---------------------------------------------------------------------------------------------			
							 
		when StopBit=>
			rst_datacounter<='1';--rst
			if(BitCounter = PulseEndOfCount) then 
				if( LineRD_in = '1') then--set when all the data rx is valid
					Fifo_write<='1';
					next_state<= Idle;
					rst_BitCounter<='1';
				else 
					next_state<= Idle;
				end if;
			end if;
		end case;
	end if;
Store_out<=Fifo_write;
end process rst;



clking: process(Clk)
begin
	if (Clk' Event and Clk ='1')then
		if (rst_BitCounter='1') then--reset the counter
			BitCounter <= (OTHERS => '0');	
		else--count
				BitCounter <= BitCounter + 1;	
		end if;
		
		if(rst_datacounter='1')then
			DataCount <= (OTHERS => '0');--reset the counter
		else--count
			if (en_counter ='1') then
				DataCount <= DataCount+1;
			end if;
		end if;
		current_state <= next_state;
	end if;
end process clking;

end Behav;

